#include <iostream>
#include "Serialize.h"
#include "Serialize_xml.h"
#include "Base64Crypt.h"

using namespace std;
using namespace Serialize;
using namespace Serialize_xml;
using namespace Base64Crypt;

//二进制序列化的自定义对象示例：1.继承自UserType;2.把对象成员写入SERIALIZE宏
struct UserDefinedType : public UserType{
    SERIALIZE(idx,name,data)
    int idx;
    std::string name;
    std::vector<double> data;
};

//需要xml序列化的自定义对象示例：1.继承自UserTypeXml;2.把对象成员写入SERIALIZE宏
class A : public UserTypeXml
{
public:
    A(){}
    A(const string& name, int age) : m_name(name),m_age(age){}
    void show(){cout << m_name << " "  << m_age << endl;}

	SERIALIZE_XML(m_name, m_age);

private:
    string m_name;
    int m_age = 0;
};


int main()
{
    int n0 = 256, n1;
    // serialize object n0 to a binary file n.data
    serialize(n0, "n.data");
    // reconstruct object n1 from the content of n.data
    deserialize(n1, "n.data");    
    // now n0 == n1 should be true.
    cout << "test 1: int n0 and n1 ,binary serialize" << endl;
    cout << "n1 = " << n1 << "; n0==n1: " << boolalpha << bool(n0==n1) << endl;
    cout << "----------------------------------------------------------------" << endl;

    std::pair<int, double> pair0 = {2, 3.1}, pair1;
    // serialize object pair0 to an XML file pair.xml with the name std_pair
    serialize_xml(pair0, "std_pair", "data.xml");
    // reconstruct object pair1 from the content of pair.xml
    deserialize_xml(pair1, "std_pair", "data.xml");
    // now pair0 == pair1 should be true.
    cout << "test 2: std::pair<int,double> pair0 and pair1 ,XML serialize" << endl;
    cout << "pair1 = {" << pair1.first << "," << pair1.second << "}; pair0==pair1: " << bool(pair0==pair1) << endl;
    cout << "----------------------------------------------------------------" << endl;

    //serialize user defined object
    UserDefinedType user1,user2;
    user1.idx = 6;
    user1.name = "ZhouYou";
    user1.data.push_back(2023.6);
    user1.data.push_back(6.13);
    serialize(user1,"user.data");
    deserialize(user2,"user.data");
    cout << "test 3: UserDefinedType user1,user2 ,binary serialize" << endl;
    cout << "user2: id = " << user2.idx << ", name = " << user2.name << ", data = {" << user2.data[0] << "," << user2.data[1] << "}" << endl;
    cout << "----------------------------------------------------------------" << endl;

    //serialize user defined object for xml
    A obj("kitty",18),ooj;
    serialize_xml(obj,"object","data.xml");
    deserialize_xml(ooj,"object","data.xml");
    cout << "test 4: user defined class A ,XML serialize" << endl;
    cout << "before serialize: " ;
    obj.show();
    cout << "after deserialize: " ;
    ooj.show();
    cout << "----------------------------------------------------------------" << endl;

    //[Bonus] Use binary-to-text encoding/decoding (base64) to implement a binary mode of XML serialization.
    cout << "test 5: use base64 to encode/decode xml" << endl;
    cout << "input:data.xml; stream:base64.txt; output:output.xml" << endl;
    encrypt("data.xml","base64.txt");       //将data.xml以base64格式编入base64.txt中
    try{
        decrypt("base64.txt","output.xml"); //将base64格式的数据解码到output.xml内
    }
    catch(...){
        cout << "解码失败" << endl;         //数据不为base64格式时解码失败
    }

}